#include "policy_container.h"

PolicyContainer::PolicyContainer(const std::string& instrument, Trader* trader) : instrument_(instrument)
{
	//TODO parse xml
	Policy::ConfigMap map;
	policy_ = new Policy(map);
	trader_ = trader;
}

void PolicyContainer::OnMarketData(const MarketData* md)
{
	last_md_ = md;
	policy_->OnMarketData(md);
	CheckPosition();
}

void PolicyContainer::SwitchDay(const std::string& trading_day)
{
	last_md_ = nullptr;
	policy_->SwitchDay(trading_day);
}

void PolicyContainer::ForceClose()
{
	if (policy_->target_position)
	{
		policy_->remark = "force";
		policy_->target_position = 0;
		CheckPosition();
	}
}

void PolicyContainer::CheckPosition()
{
	if (last_md_ == nullptr)
	{
		return;
	}
	int& target_position = policy_->target_position;
	int& current_position = policy_->current_position;
	if (target_position != current_position)
	{
		printf("Position change, time %s %s, current %d, target %d\n", last_md_->trading_day, last_md_->update_time, current_position, target_position);
		if (target_position * current_position <= 0)
		{
			if (current_position < 0)
			{
				// -1 -> 0
				trader_->Cover(instrument_, last_md_->ask_price, current_position * -1, policy_->remark);
			}
			else if (current_position > 0)
			{
				// 1 -> 0
				trader_->Sell(instrument_, last_md_->bid_price, current_position, policy_->remark);
			}

			if (target_position > 0)
			{
				// 0 -> 1
				trader_->Buy(instrument_, last_md_->ask_price, target_position);
			}
			else if (target_position < 0)
			{
				// 0 -> -1
				trader_->Short(instrument_, last_md_->bid_price, target_position * -1);
			}
		}
		else
		{
			if (current_position < target_position)
			{
				if (current_position > 0)
				{
					// 1 -> 2
					trader_->Buy(instrument_, last_md_->ask_price, target_position - current_position);
				}
				else
				{
					// -2 -> -1
					trader_->Cover(instrument_, last_md_->ask_price, target_position - current_position, policy_->remark);
				}
			}
			else
			{
				if (current_position > 0)
				{
					// 2 -> 1
					trader_->Sell(instrument_, last_md_->bid_price, current_position - target_position, policy_->remark);
				}
				else
				{
					// -1 -> -2
					trader_->Short(instrument_, last_md_->bid_price, current_position - target_position);
				}
			}
		}
		current_position = target_position;
	}
}